package com.autonavi.yunda.yunji.core.vo.param;

import com.autonavi.yunda.yunji.common.exception.AmapPreconditions;
import com.autonavi.yunda.yunji.core.utils.ValidUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;

import java.util.Objects;

import static com.autonavi.yunda.yunji.core.config.EngineConstant.*;

/**
 * @author cizhong.wcs
 * @date 2022/6/23 20:26
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NodeParam {
    public String name;
    public String type = "string";
    public String desc;
    public String defaultVal;
    public boolean require = false;
    //数据来源
    public String dataSource;
    public Object debugValue;
    //参数使用分组 目前主要是给http节点使用表示参数用法,分为query,body,headers,config
    public String paramGroup;
    public boolean emptyFlag = false;

    public NodeParam(String name, String type, String debugValue) {
        this.name = name;
        this.type = type;
        this.debugValue = debugValue;
    }

    public void checkParamWhenDebug() {
        checkParam("");
    }

    public void checkParam(String nodeName) {
        // 如果nodeName不为空，校验dataSource是否为空
        if (Strings.isNotBlank(nodeName)) {
            AmapPreconditions.checkArgumentForUser(StringUtils.isNoneBlank(dataSource), "节点" + nodeName + "中参数引用来源不能为空");
        }
        // 如果是dataSource为动态变量， debugValue不能为空
        if (DYNAMIC_CONFIG_REF.equals(dataSource)) {
            AmapPreconditions.checkArgumentForUser(
                    Objects.nonNull(debugValue) && StringUtils.isNotBlank(debugValue.toString()),
                    "节点" + nodeName + "动态变量参数 " + name + " 的变量key不能为空"
            );
        }
        //function节点参数校验更加严格
        AmapPreconditions.checkArgumentForUser(StringUtils.isNoneBlank(name), "节点" + nodeName + "中参数名称不能为空");
        // 不能含有java关键字
        AmapPreconditions.checkArgumentForUser(!INVALID_VAR_NAME_SET.contains(name), "节点" + getName() + "中参数名称不能为系统关键字");
        // 只能使用[字母,数字,-,_]且不能以数字开头
        AmapPreconditions.checkArgumentForUser(ValidUtil.checkRegexAndReturn(name, NODE_PARAM_NAME_REGEX), "节点" + nodeName + "参数名" + name + "只能使用[字母,数字,-,_]且不能以数字开头");
    }

    /**
     * 当参数名出现特殊的字符或者系统关键字时,调整参数名称
     * * 主要是处理http节点的参数 比如headers中会有"Content-Type"这种参数名
     */
    public String getParamNameInScript() {
        //符合参数规范则不调整
        if (ValidUtil.checkRegexAndReturn(name, GROOVY_SYNTAX_VARIABLE_REGEX) && !INVALID_VAR_NAME_SET.contains(name)) {
            return name;
        }
        return name.replaceAll("-", "_");
    }
}
